/*
Farmer Duel beneath an Active Volcano
(c) Rachel J. Morris, 2011
June - July 2011 project
http://www.moosader.com/

Farmer Duel - GNU GPL v3
Sader - MIT
*/

#include "StateGame.h"

StateGame::StateGame()
{
    m_code = GAME;
}

void StateGame::Init()
{
    LoadAssets();
    m_input.PopulateActionList( m_code );

    player1.Init( 1 );
    player1.SetTexture( m_textureMgr.GetAsset( "players" ) );

    player2.Init( 2 );
    player2.SetTexture( m_textureMgr.GetAsset( "players" ) );

    pong.Init();
    pong.SetTexture( m_textureMgr.GetAsset( "items" ) );
    pong.MaxY( player1.CollisionRectangle().h );

    player1Score.Init( PLAYER_1_SCORE );
    player1Score.SetTexture( m_textureMgr.GetAsset( "text-numbers" ) );

    player2Score.Init( PLAYER_2_SCORE );
    player2Score.SetTexture( m_textureMgr.GetAsset( "text-numbers" ) );

    labelWins.Init( WIN_LABEL );
    labelWins.SetTexture( m_textureMgr.GetAsset( "text-wins" ) );

    labelPlayer.Init( WIN_PLAYER_LABEL );
    labelPlayer.SetTexture( m_textureMgr.GetAsset( "text-player" ) );

    labelNumber.Init( WIN_PLAYER_NUMBER );
    labelNumber.SetTexture( m_textureMgr.GetAsset( "text-numbers" ) );

    m_camera.Init( -200, -190, -220, 25, 109, 0, 10, 2 );

    player1Boundary.SetCoordinates( 0, 0, -65 );
    player1Boundary.SetCollisionRegion( 0, -50, 0, 610, 200, 64 );

    player2Boundary.SetCoordinates( 0, 0, 615 );
    player2Boundary.SetCollisionRegion( 0, -50, 0, 610, 200, 64 );

    debug = false;

    m_playerWins = 0;
}

void StateGame::LoadAssets()
{
    std::vector<std::string> textureAssets;
    textureAssets.push_back( "tiles.png" );
    textureAssets.push_back( "items.png" );
    textureAssets.push_back( "players.png" );
    textureAssets.push_back( "text-player.png" );
    textureAssets.push_back( "text-numbers.png" );
    textureAssets.push_back( "text-wins.png" );
    std::vector<std::string> mapAssets;
    mapAssets.push_back( "farm.poo" );

    m_textureMgr.LoadAssets( textureAssets );
    m_mapMgr.LoadAssets( mapAssets, m_textureMgr.GetAsset( "tiles" ) );
}

int StateGame::MainLoop()
{
    m_input.ResetInputCooldown();
    closeState = false;
    pause = true;
    m_input.SetWindow( app );

    while ( !closeState )
    {
        app->GetEvent();
        HandleInput();

        if ( !pause && m_playerWins <= 0 )
        {
            pong.Move();

            // Collision tests
            if ( pong.CollisionTimer() <= 0 && pong.CollidingWith( &player1 ) )
            {
                pong.ChangeDirection( player1.X(), player1.Z() );
                pong.StartCollisionTimer();
            }
            if ( pong.CollisionTimer() <= 0 && pong.CollidingWith( &player2 ) )
            {
                pong.ChangeDirection( player2.X(), player2.Z() );
                pong.StartCollisionTimer();
            }
            if ( pong.CollidingWith( &player1Boundary ) )
            {
                player2.IncrementScore();
                player2Score.NumberInc();
                pong.ResetCoordinates( 2 );
            }
            if ( pong.CollidingWith( &player2Boundary ) )
            {
                player1.IncrementScore();
                player1Score.NumberInc();
                pong.ResetCoordinates( 1 );
            }

            if ( player1.Score() - player2.Score() > 3 )
            {
                labelNumber.NumberSet( 1 );
                m_playerWins = 1;
            }
            else if ( player2.Score() - player1.Score() > 3 )
            {
                labelNumber.NumberSet( 2 );
                m_playerWins = 2;
            }
        }
        Render();
    }
    return MENU;
}

void StateGame::Render()
{
    app->window.SetActive();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glTranslatef( m_camera.TransX(), m_camera.TransY(), m_camera.TransZ() );

    player1Score.Draw( sader::XY );
    player2Score.Draw( sader::XY );

    if ( m_playerWins > 0 )
    {
        labelWins.Draw( sader::XY );
        labelPlayer.Draw( sader::XY );
        labelNumber.Draw( sader::XY );
    }

    glRotatef( m_camera.RotX(), 1.0f, 0.0f, 0.0f );
    glRotatef( m_camera.RotY(), 0.0f, 1.0f, 0.0f );
    glRotatef( m_camera.RotZ(), 0.0f, 0.0f, 1.0f );

    m_mapMgr.GetAsset(0).Draw();

    player1.DrawShadow();
    player2.DrawShadow();
    pong.DrawShadow();

    player1.Draw( sader::YZ );
    player2.Draw( sader::YZ );
    pong.Draw( sader::XYYZ );

    if ( debug )
    {
        player1.DrawBoundingBox( 1.0f, 1.0f, 0.0f );
        player2.DrawBoundingBox( 1.0f, 0.0f, 1.0f );
        pong.DrawBoundingBox( 0.0f, 1.0f, 1.0f );

        player1Boundary.DrawBoundingBox( 1.0f, 1.0f, 0.0f );
        player2Boundary.DrawBoundingBox( 1.0f, 0.0f, 1.0f );
    }

    app->window.Display();
}

void StateGame::HandleInput()
{
    actions = m_input.Actions();
    m_input.Update();

    if ( actions[ STATE_MENU ] ) { closeState = true; }
    if ( actions[ TOGGLE_PAUSE ] ) { pause = !pause; m_input.ResetInputCooldown(); }
    if ( actions[ TOGGLE_DEBUG ] )
    {
        debug = !debug;
        m_input.ResetInputCooldown();
        std::cout<<"Debug Mode "<<debug<<std::endl;
    }

    if ( GameActive() )
    {
        // Player 1 movement
        if ( actions[ PLAYER_1_MOVE_UP ] )      { player2.Move( UP ); }
        if ( actions[ PLAYER_1_MOVE_DOWN ] )    { player2.Move( DOWN ); }
        // Player 2 movement
        if ( actions[ PLAYER_2_MOVE_UP ] )      { player1.Move( UP ); }
        if ( actions[ PLAYER_2_MOVE_DOWN ] )    { player1.Move( DOWN ); }
    }
}
